<template>
  <el-form ref="spuFormRef" :rules="spuFormRules" label-width="100px" :model="spuInfo">
    <el-form-item label="SPU名称" prop="spuName">
      <el-input v-model="spuInfo.spuName" placeholder="SPU名称"></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌" prop="tmId">
      <el-select placeholder="请选择" v-model="spuInfo.tmId">
        <el-option v-for="tm in trademarkList" :key="tm.id" :label="tm.tmName" :value="tm.id"></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述" prop="description">
      <el-input :rows="4" v-model="spuInfo.description" placeholder="请输入SPU描述" type="textarea"></el-input>
    </el-form-item>
    <el-form-item label="SPU图片" prop="spuImageList">
      <el-upload v-model:file-list="spuInfo.spuImageList" :action="`${baseUrl}/admin/product/fileUpload`" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <el-form-item label="销售属性" prop="spuSaleAttrList">
      <el-select :placeholder="`还有${filterBaseSaleAttrList.length}个未选择`" v-model="spuInfo.spuSaleAttr">
        <el-option v-for="baseSaleAttr in filterBaseSaleAttrList" :key="baseSaleAttr.id" :value="`${baseSaleAttr.id}:${baseSaleAttr.name}`" :label="baseSaleAttr.name"></el-option>
      </el-select>
      <el-button type="primary" :disabled="!spuInfo.spuSaleAttr" :icon="Plus" style="margin-left:10px" @click="toAddBaseSaleAttr">添加销售属性</el-button>
    </el-form-item>
    <el-form-item label="">
      <el-table border :data="spuInfo.spuSaleAttrList">
        <el-table-column label="序号" type="index" align="center" width="90px"></el-table-column>
        <el-table-column label="属性名" prop="saleAttrName" width="100px"></el-table-column>
        <el-table-column label="属性值名称列表">
          <template v-slot="{row}">
            <el-tag v-for="(tag,index) in row.spuSaleAttrValueList" :key="tag" class="mx-1" closable :disable-transitions="false" style="margin-right:4px" @close="handleClose(row,index)">
              {{ tag.saleAttrValueName }}
            </el-tag>
            <el-input v-if="row.inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20" size="small" style="width:100px" @keyup.enter="handleInputConfirm(row)" @blur="handleInputConfirm(row)" />
            <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput(row)">
              +
            </el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{row,$index}">
            <el-popconfirm confirm-button-text="Yes" cancel-button-text="No" title="真的要删除此属性吗?" @confirm="toDeleteAttr($index)">
              <template #reference>
                <div style="display: inline-block;margin-left:10px">
                  <el-tooltip class="box-item" effect="dark" content="删除属性值" placement="top">
                    <el-button type="danger" size="small" :icon="Delete"></el-button>
                  </el-tooltip>
                </div>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitSpuForm(spuFormRef)">保存</el-button>
      <el-button @click="emits('changeStatus',ShowStatus.SPU_LIST)">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
  name: 'SpuForm'
});
</script>
<script setup lang="ts">
import { ref, onMounted, reactive, computed, nextTick } from 'vue';
import { Plus, Delete } from '@element-plus/icons-vue';
import { ShowStatus } from '../types';
import { ElMessage, ElInput, type UploadProps, type UploadUserFile, type FormRules, type FormInstance } from 'element-plus';
import { reqGetAllTrademarkList, reqGetBaseSaleAttrList, reqGetSpuImageList, reqGetSpuSaleAttrList, reqSaveSpuInfo, reqUpdateSpuInfo } from '@/api/product/spu';
import { useCategoryListStore } from '@/stores/categorySelector';

const categoryStore = useCategoryListStore();
const dialogImageUrl = ref('');
const dialogVisible = ref(false);
const fileList = ref<UploadUserFile[]>([]);
const trademarkList = ref([]); // 品牌列表数据
const baseSaleAttrList = ref([]); // 销售属性列表数据
const props = defineProps(['currentSpuInfo']);
const emits = defineEmits(['changeStatus']);

const inputValue = ref('');
const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3']);
const inputVisible = ref(false);
const InputRef = ref<InstanceType<typeof ElInput>>();
const spuFormRef = ref();
const baseUrl = import.meta.env.VITE_API_URL;
// const initSpuInfo = ()=>{}
const spuInfo = reactive(props.currentSpuInfo)


// 12. 添加数据校验
// 1. 给el-form添加属性 :model="spuInfo" ref="spuFormRef" :rules=""
// 2. 给要校验的属性那一行 el-form-item添加 prop=""
// 3. 定义变量 const spuFormRef= ref()
// 4. 给确定按钮注册事件 在最后触发的时候，要统一进行校验

const spuFormRules = reactive<FormRules>({
  spuName: [
    { required: true, message: '请输入spu名称', trigger: 'blur' },
    { min: 1, max: 10, message: '品牌名称应该是在1到10之间', trigger: 'blur' }
  ],
  tmId: [{ required: true, message: '请选择spu品牌', trigger: 'change' }],
  description: [{ required: true, message: '请添加spu描述', trigger: 'blur' }],
  spuImageList: [
    {
      required: true,
      message: '请至少上传一张图片',
      trigger: 'change'
    }
  ],
  spuSaleAttrList: [
    {
      required: true,
      message: '请至少选择一个销售属性',
      trigger: 'change'
    }
  ]
});

// // 先定义一个获取所有品牌的函数
// const getAllTrademarkList = async ()=>{
//   const result = await reqGetAllTrademarkList()
//   console.log('tt',result)
// }

// // 定义获取所有的销售属性的函数
// const getBaseSaleAttrList = async () => {
//   const result = await reqGetBaseSaleAttrList()
//   console.log('bb',result)
// }

// onMounted(() => {
//   getAllTrademarkList()
//   getBaseSaleAttrList()
// })

// 1. 一次性获取所有的品牌和销售属性
onMounted(async()=>{
  try{
    let promise1 = reqGetAllTrademarkList()
    let promise2 = reqGetBaseSaleAttrList()
    let promise3;
    let promise4;
    const id = spuInfo.id
    if(id){
      promise3 = reqGetSpuImageList(id)
      promise4 = reqGetSpuSaleAttrList(id)
    }
    const [resTrademarkList,resBaseSaleAttrList,resSpuImageList,resSpuSaleAttrList]=await Promise.all([promise1,promise2,promise3,promise4])
    console.log('acc',resTrademarkList,resBaseSaleAttrList,resSpuImageList,resSpuSaleAttrList);
    trademarkList.value = resTrademarkList
    baseSaleAttrList.value = resBaseSaleAttrList
    if(resSpuImageList&&resSpuSaleAttrList){
      spuInfo.spuImageList = resSpuImageList.map(item=>{
        return{
          ...item,
          name:item.imgName,
          url:item.imaUrl
        }
      })
      spuInfo.spuSaleAttrList = resSpuSaleAttrList;
    }

  }catch(error){
    ElMessage.error('失败')
  }
})

// 2. 图片上传之前的校验
const beforeAvatarUpload: UploadProps['beforeUpload'] = rawFile => {
  // console.log('rr', rawFile);
  const imgArr = ['image/jpeg', 'image/png'];
  // if (rawFile.type !== 'image/jpeg') {
  if (!imgArr.includes(rawFile.type)) {
    ElMessage.error('图片格式必须是"image/jpeg或image/png"!');
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片大小不能超过2M!');
    return false;
  }
  return true;
};

// 3. 图片上传成功之后的链接地址
const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {
  // response是服务器端响应回来的数据 uploadFile包含的更多 包含原文件和服务器返回的数据
  // uploadFiles是一个数组 包含所有的上传成功的图片数据
  // console.log('uu', response, uploadFile, uploadFiles)

  // spuInfo.spuImageList.push({
  //   imgName: uploadFile.name,
  //   imgUrl:response.data
  // })
  spuInfo.spuImageList = uploadFiles;
  // 清除校验规则
  spuFormRef.value?.clearValidate(['spuImageList']);
};

// 4. 删除图片

const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  // console.log(uploadFile, uploadFiles)
  spuInfo.spuImageList = uploadFiles;
};

// 5. 图片预览
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 6. 添加销售属性
const toAddBaseSaleAttr = () => {
  // 当单击了"添加销售属性" 其实意味着给 el-table中的:data="spuInfo.spuSaleAttrList"数组中添加值

  // 判断一下当前的销售属性是否有属性值，如果没有属性值的话，则要提示
  const spuSaleAttrList = spuInfo.spuSaleAttrList;
  if (spuSaleAttrList.length && spuSaleAttrList.some(item => item.spuSaleAttrValueList.length === 0)) {
    // ElMessage.error('有属性值为空,请添加...')
    ElMessage({
      type: 'error',
      message: '有属性值为空,请添加属性值...'
    });
    return; // 不要再向下执行了
  }

  const [baseSaleAttrId, saleAttrName] = spuInfo.spuSaleAttr.split(':');
  spuInfo.spuSaleAttrList.push({
    inputVisible: false, // 额外添加一个属性用来控制当前行属性值的添加 不要用公共的inputVisible
    baseSaleAttrId, // 属性的id
    saleAttrName, // 属性名
    spuSaleAttrValueList: [] // 用来存储属性值
  });

  spuInfo.spuSaleAttr = '';
};

// 7. 使用计算属性来实现销售属性的添加时的移除效果
const filterBaseSaleAttrList = computed(() => {
  // 之前页面中销售属性列表的数据渲染是用的baseSaleAttrList这个数组中的数据
  return baseSaleAttrList.value.filter(baseSaleAttr => {
    // 此处的逻辑就是在spuInfo.spuSaleAttrList中有的属性，在filterBaseSaleAttrList中就不要有了
    return !spuInfo.spuSaleAttrList.find(item => item.saleAttrName === baseSaleAttr.name);
  });
});

// 8. 删除销售属性
const toDeleteAttr = index => {
  spuInfo.spuSaleAttrList.splice(index, 1);
};

// 9. 当单击添加销售属性值按钮的时候 进行切换
const showInput = row => {
  // inputVisible.value = true
  row.inputVisible = true; // 修改当前对象中的inputVisible的值
  nextTick(() => {
    InputRef.value!.input!.focus();
  });
};

// 10. 收集销售属性值  ctrl + D 快速找到下一个相同项
const handleInputConfirm = row => {
  if (inputValue.value) {
    // 判断当前添加的内容是否与之前的内容重复
    const attrValue = row.spuSaleAttrValueList.find(item => item.saleAttrValueName === inputValue.value);
    if (attrValue) {
      ElMessage.error('当前属性值与之前的重复,请换一个...');
      row.inputVisible = false;
      inputValue.value = '';
      return;
    }

    // dynamicTags.value.push(inputValue.value)
    const { baseSaleAttrId, saleAttrName } = row;
    row.spuSaleAttrValueList.push({
      baseSaleAttrId,
      isChecked: '0',
      saleAttrName,
      saleAttrValueName: inputValue.value
    });
  }
  // inputVisible.value = false
  row.inputVisible = false;
  inputValue.value = '';
};

// 11. 删除某个销售属性值
const handleClose = (row, index) => {
  // dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1)
  row.spuSaleAttrValueList.splice(index, 1);
};

// 13. 实现spuInfo的添加
const submitSpuForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      spuInfo.category3Id = categoryStore.category3Id as number;
      // 将要上传的图片列表中的数据格式进行统一处理 因为服务器端需要imgName imgUrl
      spuInfo.spuImageList = spuInfo.spuImageList.map(item => {
        return {
          imgName: item.name as string,
          imgUrl: item.response? item.response.data : item.imgUrl
        };
      });

      // 判断销售属性值是否为空
      const spuSaleAttrList = spuInfo.spuSaleAttrList;
      const flag = spuSaleAttrList.length && spuSaleAttrList.every(item => item.spuSaleAttrValueList.length !== 0);
      if (!flag) {
        ElMessage.error('有属性值为空,请添加...');
        return;
      }
      if(spuInfo.id){
        //如果有id 则是更新
        await reqUpdateSpuInfo(spuInfo)
        ElMessage.success('更新spu数据成功了')
      }else{
        await reqSaveSpuInfo(spuInfo);
        ElMessage.success('添加spu数据成功了')
      }
      // 发送请求 实现spu数据的添加
      
      // 提示用户 添加成功了
      emits('changeStatus', ShowStatus.SPU_LIST);
    } else {
      console.log('error submit!', fields);
    }
  });
};

</script>

<style scoped>
</style>